package kernel_gui.gui.extended;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import kernel_gui.gui.generic.graphic.CreateQuestion;

import common.entities.enums.PATTERN;
import common.entities.persistent.Actor;
import common.entities.persistent.Director;
import common.entities.persistent.Genre;
import common.entities.persistent.Movie;

public class ECreateQuestion extends CreateQuestion {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6178769593245070764L;
	private int choosenQuestionLevel = 2;
	private DefaultComboBoxModel<PATTERN> patternsModel;
	private PATTERN selectedPattern;
	
	
	/*this is a parameter that will be sent to kernel*/
	private int questionParamToKer;
	private int answerParamToKer;
	/*here holding the object of the parameter to kernel*/
	private Movie parameterMovie;
	private Actor parameterActor;
	private Director parameterDirector;
	private int parameterYear;
	
	private Movie answerMovie;
	private Actor answerActor;
	private Genre answerGenre;
	
	private boolean enableSubmit;
	
	
	@SuppressWarnings("unchecked")
	public ECreateQuestion(){
		/*Command to execute on cancel*/
		setExecuteOnCancel(new CommandToExecute() {
			
			@Override
			public void command(Object answer) {
				Component components[] = MainPanel.getComponents();
				for (Component c : components) {
					if(c instanceof JPanel){
						JPanel panel = (JPanel) c;
						Component pcomponents[] = panel.getComponents();
						for(Component pc : pcomponents){
							if(pc instanceof JPanel){
								JPanel anotherPanel = (JPanel) pc;
								Component pccomponents[] = anotherPanel.getComponents();
								for(Component pcc : pccomponents){
									pcc.setEnabled(true);
								}
							}
							pc.setEnabled(true);
						}
					}
					c.setEnabled(true);
				}
				if(!enableSubmit)
					SubmitButton.setEnabled(false);
			}
		});
		
		/*Command to execute before long request*/
		setExecuteBeforeLongRequest(new CommandToExecute() {
			
			@Override
			public void command(Object answer) {
				Component components[] = MainPanel.getComponents();
				for (Component c : components) {
					if(c instanceof JPanel){
						JPanel panel = (JPanel) c;
						Component pcomponents[] = panel.getComponents();
						for(Component pc : pcomponents){
							if(pc instanceof JPanel){
								JPanel anotherPanel = (JPanel) pc;
								Component pccomponents[] = anotherPanel.getComponents();
								for(Component pcc : pccomponents){
									pcc.setEnabled(false);
								}
							}
							pc.setEnabled(false);
						}
					}
					c.setEnabled(false);
				}
			}
		});
		
		/*Init the parameters to the pattern - non where selected yet*/
		initQuestionParameters();
		/*init choosen right answer label, non was selected yet*/
		changeChoosenRightAnswer(null);
		/*init the ddb with Patterns*/
		patternsModel = new DefaultComboBoxModel<PATTERN>(PATTERN.values());
		choosenPatternComboBox.setModel(patternsModel);
		updateChoosenPattern();
	}
	
	@Override
	protected void dynamicButtonActionPerformed(ActionEvent evt) {
		if(selectedPattern != PATTERN.MOVIE_RELEASED_IN_YEAR){
			/*Command to execute after returning from*/
			CommandToExecute cte = new CommandToExecute() {
				
				@Override
				public void command(Object answer) {
					if(answer != null){
						/*There are answers for this question*/
						switch(selectedPattern){
						case ACTOR_PLAYED_IN_MOVIE:
							parameterMovie = (Movie)answer;
							questionParamToKer = parameterMovie.getId();
							updateChoosenQuestionParameter(parameterMovie, null, null, -1);
							break;
						case GENRE_OF_MOVIE:
							parameterMovie = (Movie)answer;
							questionParamToKer = parameterMovie.getId();
							updateChoosenQuestionParameter(parameterMovie, null, null, -1);
							break;
						case MOVIE_ACTOR_IN://
							parameterActor = (Actor)answer;
							questionParamToKer = parameterActor.getId();
							updateChoosenQuestionParameter(null, parameterActor, null, -1);
							break;
						case MOVIE_DIRECTED_BY:
							parameterDirector = (Director)answer;
							questionParamToKer = parameterDirector.getId();
							updateChoosenQuestionParameter(null, null, parameterDirector, -1);
							break;
						}
					}else{
						JOptionPane.showMessageDialog(ECreateQuestion.this, "Please choose a question parameter if you wish"
								+ "to create a question.");
					}
				}
			};
			
			switch(selectedPattern){
				case ACTOR_PLAYED_IN_MOVIE:{
					openAnotherFrame(EControlMovies.class, false, cte);
					break;
				}
				case GENRE_OF_MOVIE:{
					openAnotherFrame(EControlMovies.class, false, cte);
					break;
				}
				case MOVIE_ACTOR_IN:{
					openAnotherFrame(EControlActors.class, false, cte);
					break;
				}
				case MOVIE_DIRECTED_BY:{
					openAnotherFrame(EControlDirectors.class, false, cte);
					break;
				}
			}
		}else{ /*we need a year*/
			
			/*prompt user for year input*/
			String userInput = JOptionPane.showInputDialog(this, "Please type a year value between " + 
					Movie.releaseYearMinValue + "-" + Movie.releaseYearMaxValue + " (including)",
						"Choose Year", JOptionPane.QUESTION_MESSAGE);
			
			/*check user input*/
			int userInput_INT = -1;
			try{
				userInput_INT = Integer.parseInt(userInput);
			}catch (NumberFormatException e) {
				/*prompt to user after*/
			}
			
			if(userInput_INT == -1){
				JOptionPane.showMessageDialog(this, "Please enter a NUMBER.");
			}else if (userInput_INT < Movie.releaseYearMinValue || userInput_INT > Movie.releaseYearMaxValue){
				JOptionPane.showMessageDialog(this, "The number isn't between " + 
					Movie.releaseYearMinValue + "-" + Movie.releaseYearMaxValue + " (including).");
			}else{
				this.parameterYear = userInput_INT;
				updateChoosenQuestionParameter(null, null, null, this.parameterYear);
			}
		}
	}

	@Override
	protected void SubmitButtonActionPerformed(ActionEvent evt) {
		/*Command to execute after returning from*/
		int requestID = executeBeforeLongRequest(new CommandToExecute() {
			
			@Override
			public void command(Object answer) {
				if(((Boolean)answer) == true){
					changeChoosenRightAnswer("Your question was created, you can create more!");
					RightAnswerLabel.setForeground(Color.GREEN);
					ECreateQuestion.this.resetAfterSubmit();
				}
			}
		});
	
		
		kernel.setRightAnswer(selectedPattern, questionParamToKer, answerParamToKer, choosenQuestionLevel, requestID);

	}

	private void resetAfterSubmit(){
		/*reset changes caused by creating the question*/
		initQuestionParameters();
		updateQuestionToUserWithParameter(null);
		
		enableSubmit = false;
		SubmitButton.setEnabled(false);
		MediumRadioButton.setSelected(true);
		/*NOT resetting the choosen pattern*/
	}
	
	private void updateChoosenPattern(){
		selectedPattern = (PATTERN)choosenPatternComboBox.getSelectedItem();
		changeChoosenRightAnswer(null);
		resetAfterSubmit();
	}
	
	private void updateQuestionToUserWithParameter(String qParam){
		if(qParam == null)
			QuestionLabel.setText(parseStringIntoFixedSize(6, 94, selectedPattern.getUserPatternFormat()));
		else
			QuestionLabel.setText(parseStringIntoFixedSize(6, 94, 
					String.format(selectedPattern.getPatternFormat(), qParam)));
	}
	
	@Override
	protected void choosePatternComboBoxActionPerformed(ActionEvent evt) {
		updateChoosenPattern();
	}

	@Override
	protected void BackButtonActionPerformed(ActionEvent evt) {
		openAnotherFrame(EControlQuestions.class, true);
	}

	@Override
	protected void HardRadioButtonActionPerformed(ActionEvent evt) {
		this.choosenQuestionLevel = 3;
		
	}

	@Override
	protected void MediumRadioButtonActionPerformed(ActionEvent evt) {
		this.choosenQuestionLevel = 2;
		
	}

	@Override
	protected void EasyRadioButtonActionPerformed(ActionEvent evt) {
		this.choosenQuestionLevel = 1;
		
	}
	
	protected void initQuestionParameters(){
		questionParamToKer = -1;
		
		parameterMovie = null;
		parameterActor = null;
		parameterDirector = null;
		parameterYear = -1;
	}
	
	private void updateChoosenQuestionParameter(Movie movie, Actor actor, Director director, int year){
		initQuestionParameters();
		if(movie != null){
			questionParamToKer = movie.getId();
			this.parameterMovie = movie;
			updateQuestionToUserWithParameter(movie.getTitle());
		}else if(actor != null){
			questionParamToKer = actor.getId();
			this.parameterActor = actor;
			updateQuestionToUserWithParameter(actor.getLastName() + ", " + actor.getFirstName());
		}else if(director != null){
			questionParamToKer = director.getId();
			this.parameterDirector = director;
			updateQuestionToUserWithParameter(director.getLastName() + ", " + director.getFirstName());
		}else if(year != -1){
			questionParamToKer = year;
			this.parameterYear = year;
			updateQuestionToUserWithParameter(String.valueOf(year));
		}else{
			throw new IllegalArgumentException("ECreateQuestion: at least one of the parameters must be provided");
		}
		
		
		/*Command to execute after returning from*/
		int requestID = executeBeforeLongRequest(new CommandToExecute() {
			
			@Override
			public void command(Object answer) {
				if(((Boolean)answer) == true){
					ECreateQuestion.this.openAnswersFrame();
				}
			}
		});
		
		kernel.createQuestion(selectedPattern, questionParamToKer, requestID);
		
	}
	
	protected void openAnswersFrame() {
		
		CommandToExecute cte = new CommandToExecute() {
			
			@Override
			public void command(Object answer) {
				if(answer != null){
					switch(selectedPattern){
					case ACTOR_PLAYED_IN_MOVIE:
						answerActor = (Actor)answer;
						answerParamToKer = answerActor.getId();
						changeChoosenRightAnswer("You have selected " + answerActor.getLastName() + ", " + answerActor.getFirstName() +	" as your RIGHT answer.\n" +
								"Submit to save question.");
						break;
					case GENRE_OF_MOVIE:
						answerGenre = (Genre)answer;
						answerParamToKer = answerGenre.getId();
						changeChoosenRightAnswer("You have selected " + answerGenre.getName() + " as your RIGHT answer.\n" +
								"Submit to save question.");
						break;
					case MOVIE_ACTOR_IN:
						answerMovie= (Movie)answer;
						answerParamToKer = answerMovie.getId();
						changeChoosenRightAnswer("You have selected " + answerMovie.getTitle() + " (" + answerMovie.getReleaseYear() + ")" +
						" as your RIGHT answer.\n" +
								"Submit to save question.");
						break;
					case MOVIE_DIRECTED_BY:
						answerMovie= (Movie)answer;
						answerParamToKer = answerMovie.getId();
						changeChoosenRightAnswer("You have selected " + answerMovie.getTitle() +
								" (" + answerMovie.getReleaseYear() + ")" + " as your RIGHT answer.\n" +
								"Submit to save question.");
						break;
					case MOVIE_RELEASED_IN_YEAR:
						answerMovie= (Movie)answer;
						answerParamToKer = answerMovie.getId();
						changeChoosenRightAnswer("You have selected " + answerMovie.getTitle() + " (" + 
						answerMovie.getReleaseYear() + ")" + " as your RIGHT answer.\n" +
								"Submit to save question.");
						RightAnswerLabel.setForeground(Color.RED);
					}
					RightAnswerLabel.setForeground(Color.RED);
					enableSubmit = true;
					SubmitButton.setEnabled(true);
				}else{
					changeChoosenRightAnswer("You HAVE to select a right answer in order to create a question.");
					resetAfterSubmit();
				}
			}
		};
		
		openPreCreatedFrame(new EAnswersFrame(this.selectedPattern, this.questionParamToKer), cte);
	}

	private void changeChoosenRightAnswer(String msgLabel){
		RightAnswerLabel.setForeground(QuestionLabel.getForeground());
		if(msgLabel == null){
			RightAnswerLabel.setText("Choose a Question-Pattern, a Parameter and a Right-Answer to create a Question.");
		}else{
			RightAnswerLabel.setText(msgLabel);
		}
	}

	@Override
	protected void setWindowComponentsWhenCalledFromAnotherFrame() {
		/*not needed*/

	}
}
